import { LeftOutlined, RightOutlined } from '@ant-design/icons'
import { formatTime } from '@gnlab/utils'
import { Input, Button, Table, message, Popconfirm } from 'antd'
import type { ColumnProps } from 'antd/lib/table'
import { EditModal } from '@/desktop/components'
import services from '@/services'
import type { OfficialData, SearchedOfficial } from '@/services/features/new-rank'
import './search.module.less'

export function Search({
  contactId,
  open,
  onClose,
}: {
  contactId: string
  open: boolean
  onClose: (data?: OfficialData) => void
}) {
  return <EditModal open={open} title="查找公众号" width={900} onCancel={() => onClose()}>
    {open ? <Content contactId={contactId} onClose={onClose} /> : null}
  </EditModal>
}

function Content({
  contactId,
  onClose,
}: {
  contactId: string
  onClose: (data?: OfficialData) => void
}) {
  const [keyword, setKeyword] = useState('')
  const trimedKeyword = keyword.trim()

  const [searched, setSearched] = useState<{
    items: SearchedOfficial[]
    keyword: string
    page: number
    finished: boolean // 是否已没有下一页数据
  }>({ items: [], keyword: '', page: 1, finished: false })
  const [searching, setSearching] = useState(false)
  async function search() {
    if (searching || !trimedKeyword.length) return

    setSearching(true)
    const res = await services.features.newRank.search(trimedKeyword, 1)
    setSearching(false)
    if (res.success) {
      setSearched({
        items: res.data ? [res.data] : [],
        keyword: trimedKeyword,
        page: 1,
        finished: false,
      })
      if (!res.data) void message.warning('未搜索到公众号')
    } else {
      void message.warning('搜索公众号失败：' + res.error)
    }
  }
  async function goPage(next = true) {
    const { keyword, page, items } = searched
    if (searching || !items.length) return

    const newPage = next ? page + 1 : page - 1
    setSearching(true)
    const res = await services.features.newRank.search(keyword, newPage)
    setSearching(false)
    if (res.success) {
      if (res.data) {
        setSearched({
          items: [res.data],
          keyword,
          page: newPage,
          finished: false,
        })
      } else if (next) {
        setSearched(searched => ({ ...searched, finished: true }))
        void message.warning('已到最后一页')
      } else {
        setSearched(searched => ({ ...searched, page: newPage }))
        void message.warning('未获取到上一页数据')
      }
    } else {
      void message.warning('搜索公众号失败：' + res.error)
    }
  }

  const [fetching, setFetching] = useState(false)
  async function fetchData(ghid: string) {
    if (fetching) return
    setFetching(true)

    setFetching(true)
    const res = await services.features.newRank.fetchDataFromNewRank(contactId, ghid)
    setFetching(false)
    if (res.success) {
      if (res.data) {
        void message.success('数据获取成功')
        onClose(res.data)
      } else {
        void message.warning('未拉取到公众号信息')
      }
    } else {
      void message.warning('新榜接口拉取公众号信息失败：' + res.error)
    }
  }

  function renderInfo(data: SearchedOfficial) {
    return <div styleName="info-box">
      <img src={data.avatar} />
      <div styleName="info">
        <div styleName="name">{data.name}</div>
        <div styleName="account">{data.account}</div>
        <div styleName="ghid">{data.ghid}</div>
      </div>
    </div>
  }

  function renderActions(data: SearchedOfficial) {
    return <Popconfirm
      title={
        <>
          <div>点击“确定”，将获取公众号“{data.name}”的数据，</div>
          <div>并展示在该用户的侧边栏，将会覆盖原有数据。</div>
        </>
      }
      onConfirm={() => void fetchData(data.ghid)}
    >
      <a>获取数据</a>
    </Popconfirm>
  }

  const columns: ColumnProps<SearchedOfficial>[] = [
    { title: '公众号名称', width: 250, render: renderInfo },
    { title: '类型', dataIndex: 'type', width: 100 },
    {
      title: '新榜采集时间',
      width: 120,
      render(data: SearchedOfficial) {
        return formatTime(data.joined)
      },
    },
    {
      title: '描述',
      width: 230,
      render(data: SearchedOfficial) {
        return <div styleName="description">{data.description}</div>
      },
    },
    { title: '新榜周指数', width: 110, dataIndex: 'weekNri' },
    { title: '操作', width: 100, render: renderActions },
  ]

  return <main styleName="wrap">
    <header>
      <div styleName="form">
        <Input
          value={keyword}
          placeholder="请输入关键词"
          autoFocus
          onChange={e => setKeyword(e.target.value)}
          onKeyUp={e => {
            if (e.key === 'Enter' || e.code === 'Enter') {
              void search()
            }
          }}
        />
        <Button type="primary" disabled={!trimedKeyword.length} onClick={search}>
          查询
        </Button>
      </div>
      <div styleName="tips">
        注意：查询代价高昂，请尽量使用在较少查询次数内能获得预期结果的查询策略
      </div>
    </header>

    <div styleName="result-title">结果：</div>
    <Table loading={searching} dataSource={searched.items} columns={columns} pagination={false} />
    {searched.items.length ? (
      <div styleName="pagination">
        <Button
          type="primary"
          disabled={searching || searched.page === 1}
          onClick={async () => goPage(false)}
        >
          <LeftOutlined />
          上一页
        </Button>
        <Button
          type="primary"
          disabled={searching || searched.finished}
          onClick={async () => goPage(true)}
        >
          下一页
          <RightOutlined />
        </Button>
      </div>
    ) : null}
  </main>
}
